
#ifndef _WEAK_FD_H_20181002_
#define _WEAK_FD_H_20181002_

#include "smart_fd_inner.hpp"

namespace SmartFd {

WeakFd::WeakFd()
    : detail_(NULL)
{ }

WeakFd::WeakFd(const WeakFd &other)
    : detail_(other.detail_)
{
    if (other.detail_ != NULL)
        detail_->weakRef();
}

WeakFd::WeakFd(const SharedFd &other)
    : detail_(other.detail_)
{
    if (other.detail_ != NULL)
        detail_->weakRef();
}

void WeakFd::swap(WeakFd &other)
{
    if (this == &other)
        return;

    std::swap(detail_, other.detail_);
}

void WeakFd::reset()
{
    WeakFd().swap(*this);
}

bool WeakFd::empty() const
{
    return detail_ == NULL;
}

WeakFd& WeakFd::operator = (const WeakFd &other)
{
    if (detail_ == NULL)
        return *this;

    reset();
    detail_ = other.detail_;

    if (detail_ != NULL)
        detail_->weakRef();
}

WeakFd& WeakFd::operator = (const SharedFd &other)
{
    reset();
    detail_ = other.detail_;

    if (detail_ != NULL)
        detail_->weakRef();
}


WeakFd::~WeakFd()
{
    if (detail_ != NULL) {
        detail_->weakUnref();
        if (!detail_->anyRef()) {
            delete detail_;
        }
    }
}

bool WeakFd::expired() const
{
    return detail_ == NULL || detail_->getSharedCount() == 0;
}

bool WeakFd::owner_before(const WeakFd &other) const
{
    return detail_ < other.detail_;
}

bool WeakFd::owner_after(const WeakFd &other) const
{
    return detail_ > other.detail_;
}

inline bool operator < (const WeakFd &lhs, const WeakFd &rhs) {
    return lhs.owner_before(rhs);
}

inline bool operator > (const WeakFd &lhs, const WeakFd &rhs) {
    return lhs.owner_after(rhs);
}

inline bool operator == (const WeakFd &lhs, const WeakFd &rhs) {
    return !lhs.owner_before(rhs) && !lhs.owner_after(rhs);
}

inline bool operator != (const WeakFd &lhs, const WeakFd &rhs) {
    return lhs.owner_before(rhs) || lhs.owner_after(rhs);
}

inline void swap(WeakFd &lhs, WeakFd &rhs) {
    lhs.swap(rhs);
}

}

typedef SmartFd::WeakFd WeakFd;

#endif //_WEAK_FD_H_20181002_
